#pragma once

#include <iostream>
#include <memory>
#include "Socket.hpp"
#include "Log.hpp"
#include "Connection.hpp"
#include "IOService.hpp"
#include "Calculator.hpp"

using namespace SocketModule;
using namespace LogModule;

// 专门负责获取连接的模块
class Listener : public Connection
{
public:
    Listener(uint16_t port)
        : _port(port)
        , _listensock(std::make_shared<TcpSocket>())
    {
        _listensock->BuildTcpSocketMethod(_port);
        SetSockfd(_listensock->Fd());
        SetEvents(EPOLLIN | EPOLLET);
    }

    // 回调到这里，天然就有connection
    virtual void Recver() override
    {
        // listensockfd就绪，接着获取新链接
        // 一次可能来多个链接
        // 怎么保证一次读完？循环读取，ET模式下文件描述符必须是非阻塞的
        while (true)
        {
            InetAddr peer;
            int out_errno = 0;
            int sockfd = _listensock->Accepter(&peer, &out_errno);
            if (sockfd > 0)
            {
                // 不能直接读取，需要将sockfd添加到epool中，而epoll只管理connection
                // auto conn = Factory::BuildConnection(sockfd, EPOLLIN | EPOLLET, nullptr, nullptr, nullptr);
                // 设置客户端信息
                // conn->SetPeerInfo(peer);
                LOG(LogLevel::DEBUG) << "accepter success: " << sockfd;
                // 处理普通的文件描述符

                // 1.设置文件描述符非阻塞
                SetNonBlock(sockfd);

                // 2.包装成connection
                auto conn = std::make_shared<IOService>(sockfd);
                conn->RegisterOnMessage(HandlerRequest); // 将业务注册进连接中

                // 3.插入到epollserver，通过父类的回指指针
                GetOwner()->InsertConnection(conn);
            }
            else // 获取链接失败
            {
                // 原因1：获取完了
                if (out_errno == EAGAIN || out_errno == EWOULDBLOCK)
                {
                    LOG(LogLevel::DEBUG) << "accepter all connection ... done";
                    break;
                }
                // 原因2：被信号中断了
                else if (out_errno == EINTR)
                {
                    LOG(LogLevel::DEBUG) << "accetper intr by signal, continue";
                    continue;
                }
                // 原因3：读取失败了
                else
                {
                    LOG(LogLevel::WARNING) << "accepter error ... ignore";
                    break;
                }
            }
        }
    }
    virtual void Sender() override
    {

    }

    virtual void Excepter() override
    {
        
    }

    int Sockfd() { return _listensock->Fd(); }

    ~Listener()
    {
        _listensock->Close();
    }
private:
    uint16_t _port;
    std::shared_ptr<Socket> _listensock;
};